/*
 * Copyright (C) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup AVScreenCapture
 * @{
 *
 * @brief 调用本模块下的接口，应用可以完成屏幕录制的功能。
 * @since 10
 */

/**
 * @file native_avscreen_capture_base.h
 *
 * @brief 声明用于运行屏幕录制通用的结构体、字符常量、枚举。
 *
 * @library libnative_avscreen_capture.so
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 * @kit MediaKit
 * @include <multimedia/player_framework/native_avscreen_capture_base.h>
 * @since 10
 */

#ifndef NATIVE_AVSCREEN_CAPTURE_BASE_H
#define NATIVE_AVSCREEN_CAPTURE_BASE_H

#include <stdbool.h>
#include <stdint.h>
#include "native_avbuffer.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief 提供录屏的视频原始码流类。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 *
 * @since 10
 * @version 1.0
 */
typedef struct OH_NativeBuffer OH_NativeBuffer;

/**
 * @brief 通过OH_AVScreenCapture可以获取视频与音频的原始码流。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 *
 * @since 10
 * @version 1.0
 */
typedef struct OH_AVScreenCapture OH_AVScreenCapture;

/**
 * @brief 通过OH_AVScreenCapture_ContentFilter过滤音视频内容。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 *
 * @since 12
 * @version 1.0
 */
typedef struct OH_AVScreenCapture_ContentFilter OH_AVScreenCapture_ContentFilter;

/**
 * @brief 枚举，表示屏幕录制的不同模式。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 *
 * @since 10
 * @version 1.0
 */
typedef enum OH_CaptureMode {
    /** 录制主屏幕。 **/
    OH_CAPTURE_HOME_SCREEN = 0,
    /** 录制指定屏幕。 **/
    OH_CAPTURE_SPECIFIED_SCREEN = 1,
    /** 录制指定窗口。 **/
    OH_CAPTURE_SPECIFIED_WINDOW = 2,
	/** 无效模式。 **/
    OH_CAPTURE_INVAILD = -1
} OH_CaptureMode;

/**
 * @brief 枚举，表示屏幕录制时的音频源类型。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 *
 * @since 10
 * @version 1.0
 */
typedef enum OH_AudioCaptureSourceType {
    /** 无效音频源。 **/
    OH_SOURCE_INVALID = -1,
    /** 默认音频源，默认为麦克风。 **/
    OH_SOURCE_DEFAULT = 0,
    /** 麦克风录制的外部音频流。 **/
    OH_MIC = 1,
    /** 系统播放的所有内部音频流。 **/
    OH_ALL_PLAYBACK = 2,
    /** 指定应用播放的内部音频流。 **/
    OH_APP_PLAYBACK = 3,
} OH_AudioCaptureSourceType;

/**
 * @brief 枚举，表示音频编码格式。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 *
 * @since 10
 * @version 1.0
 */
typedef enum OH_AudioCodecFormat {
    /** 默认音频编码，默认为AAC_LC。 **/
    OH_AUDIO_DEFAULT = 0,
    /** AAC_LC音频编码。 **/
    OH_AAC_LC = 3,
    /** 无效格式。 **/
    OH_AUDIO_CODEC_FORMAT_BUTT,
} OH_AudioCodecFormat;

/**
 * @brief 枚举，表示视频编码格式。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 *
 * @since 10
 * @version 1.0
 */
typedef enum OH_VideoCodecFormat {
    /** 默认视频编码，默认为H.264。 **/
    OH_VIDEO_DEFAULT = 0,
    /** H.264。 **/
    OH_H264 = 2,
    /** H.265/HEVC。 **/
    OH_H265 = 4,
    /** MPEG4。 **/
    OH_MPEG4 = 6,
    /** VP8。 **/
    OH_VP8 = 8,
    /** VP9。 **/
    OH_VP9 = 10,
    /** 无效格式。 **/
    OH_VIDEO_CODEC_FORMAT_BUTT,
} OH_VideoCodecFormat;

/**
 * @brief 枚举，表示屏幕录制流的数据格式。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 *
 * @since 10
 * @version 1.0
 */
typedef enum OH_DataType {
    /** 原始流格式，如YUV/RGBA/PCM等。 **/
    OH_ORIGINAL_STREAM = 0,
    /** 编码格式，如H264/AAC等。当前版本暂不支持。 **/
    OH_ENCODED_STREAM = 1,
    /** 保存文件格式，支持mp4。 **/
    OH_CAPTURE_FILE = 2,
    /** 无效格式。 **/
    OH_INVAILD = -1
} OH_DataType;

/**
 * @brief 枚举，表示视频源格式。当前仅支持RGBA格式。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 *
 * @since 10
 * @version 1.0
 */
typedef enum OH_VideoSourceType {
    /** YUV格式。当前版本暂不支持。 **/
    OH_VIDEO_SOURCE_SURFACE_YUV = 0,
    /** raw格式。当前版本暂不支持。 **/
    OH_VIDEO_SOURCE_SURFACE_ES,
    /** RGBA格式。 **/
    OH_VIDEO_SOURCE_SURFACE_RGBA,
    /** 无效格式。 **/
    OH_VIDEO_SOURCE_BUTT
} OH_VideoSourceType;

/**
 * @brief 枚举，表示屏幕录制生成的文件类型。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 *
 * @since 10
 * @version 1.0
 */
typedef enum OH_ContainerFormatType {
    /** 音频格式 m4a。 **/
    CFT_MPEG_4A = 0,
    /** 视频格式 mp4。 **/
    CFT_MPEG_4 = 1
} OH_ContainerFormatType;

/**
 * @brief 音频采样信息。\n
 * 当audioSampleRate和audioChannels同时为0时，忽略该类型音频相关参数，不录制该类型音频数据。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 *
 * @since 10
 * @version 1.0
 */
typedef struct OH_AudioCaptureInfo {
    /** 音频采样率，支持列表请查阅Audio Kit的AudioSamplingRate。 **/
    int32_t audioSampleRate;
    /** 音频声道数。 **/
    int32_t audioChannels;
    /** 音频源。 **/
    OH_AudioCaptureSourceType audioSource;
} OH_AudioCaptureInfo;

/**
 * @brief 音频编码信息。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 *
 * @since 10
 * @version 1.0
 */
typedef struct OH_AudioEncInfo {
    /** 音频编码比特率。 **/
    int32_t audioBitrate;
    /** 音频编码格式。 **/
    OH_AudioCodecFormat audioCodecformat;
} OH_AudioEncInfo;

/**
 * @brief 音频信息。\n
 * 同时采集音频麦克风和音频内录数据时，两路音频的audioSampleRate和audioChannels采样参数需要相同。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 *
 * @since 10
 * @version 1.0
 */
typedef struct OH_AudioInfo {
    /** 音频麦克风采样信息。 **/
    OH_AudioCaptureInfo micCapInfo;
    /** 音频内录采样信息。 **/
    OH_AudioCaptureInfo innerCapInfo;
    /** 音频编码信息，原始码流时不需要设置。 **/
    OH_AudioEncInfo audioEncInfo;
} OH_AudioInfo;

/**
 * @brief 视频录制信息。当videoFrameWidth和videoFrameHeight同时为0时，忽略视频相关参数不录制屏幕数据。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 *
 * @since 10
 * @version 1.0
 */
typedef struct OH_VideoCaptureInfo {
    /** 录制物理屏id，使用该参数需要在capturemode为CAPTURE_SPECIFIED_SCREEN模式下使用。 **/
    uint64_t displayId;
    /** 指定窗口id列表，使用该参数需要在capturemode为CAPTURE_SPECIFIED_WINDOW模式下使用 **/
    int32_t *missionIDs;
    /** 指定窗口ID长度，使用该参数需要在capturemode为CAPTURE_SPECIFIED_WINDOW模式下使用。 **/
    int32_t missionIDsLen;
    /** 采集视频的宽度设置，单位px。 **/
    int32_t videoFrameWidth;
    /** 采集视频的高度设置，单位px。 **/
    int32_t videoFrameHeight;
    /** 视频采集格式设置，目前仅支持RGBA格式。 **/
    OH_VideoSourceType videoSource;
} OH_VideoCaptureInfo;

/**
 * @brief 视频编码参数。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 *
 * @since 10
 * @version 1.0
 */
typedef struct OH_VideoEncInfo {
    /** 视频采集编码格式。 **/
    OH_VideoCodecFormat videoCodec;
    /** 视频采集比特率。 **/
    int32_t videoBitrate;
    /** 视频采集帧率。 **/
    int32_t videoFrameRate;
} OH_VideoEncInfo;

/**
 * @brief 视频信息。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 *
 * @since 10
 * @version 1.0
 */
typedef struct OH_VideoInfo {
    /** 视频采集信息。 **/
    OH_VideoCaptureInfo videoCapInfo;
    /** 视频编码参数。 **/
    OH_VideoEncInfo videoEncInfo;
} OH_VideoInfo;

/**
 * @brief 录制文件信息。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 *
 * @since 10
 * @version 1.0
 */
typedef struct OH_RecorderInfo {
    /** 录制文件的URL。 **/
    char *url;
    /** 录制文件的URL长度。 **/
    uint32_t urlLen;
    /** 录制文件的格式。 **/
    OH_ContainerFormatType fileFormat;
} OH_RecorderInfo;

/**
 * @brief 屏幕录制配置参数。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 *
 * @since 10
 * @version 1.0
 */
typedef struct OH_AVScreenCaptureConfig {
    /** 屏幕录制的模式。 **/
    OH_CaptureMode captureMode;
    /** 屏幕录制流的数据格式。 **/
    OH_DataType dataType;
    /** 音频录制参数。 **/
    OH_AudioInfo audioInfo;
    /** 视频录制参数。 **/
    OH_VideoInfo videoInfo;
    /** 录制文件参数，当数据格式为OH_CAPTURE_FILE时必须设置。 **/
    OH_RecorderInfo recorderInfo;
} OH_AVScreenCaptureConfig;

/**
 * @brief 当OH_AVScreenCapture实例运行出错时，将调用函数指针。\n
 * 从API 12开始，推荐使用接口{@link OH_AVScreenCapture_OnError}替代。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 * @param capture 指向OH_AVScreenCapture实例的指针。
 * @param errorCode 指定错误码。
 *
 * @since 10
 * @version 1.0
 */
typedef void (*OH_AVScreenCaptureOnError)(OH_AVScreenCapture *capture, int32_t errorCode);

/**
 * @brief 当OH_AVScreenCapture实例操作期间音频缓存区可用时，将调用函数指针。\n
 * 从API 12开始，推荐使用接口{@link OH_AVScreenCapture_OnBufferAvailable}替代。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 * @param capture 指向OH_AVScreenCapture实例的指针。
 * @param isReady 音频缓存区是否可用。
 * @param type 音频源类型。
 *
 * @since 10
 * @version 1.0
 */
typedef void (*OH_AVScreenCaptureOnAudioBufferAvailable)(OH_AVScreenCapture *capture, bool isReady,
    OH_AudioCaptureSourceType type);

/**
 * @brief 当OH_AVScreenCapture实例操作期间视频缓存区可用时，将调用函数指针。\n
 * 从API 12开始，推荐使用接口{@link OH_AVScreenCapture_OnBufferAvailable}替代。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 * @param capture 指向OH_AVScreenCapture实例的指针。
 * @param isReady 视频缓存区是否可用。
 *
 * @since 10
 * @version 1.0
 */
typedef void (*OH_AVScreenCaptureOnVideoBufferAvailable)(OH_AVScreenCapture *capture, bool isReady);

/**
 * @brief OH_AVScreenCapture中所有异步回调函数指针的集合。将该结构体的实例注册到OH_AVScreenCapture实例中，并处理回调上报的信息，以保证OH_AVScreenCapture的正常运行。\n
 * 从API 12开始，推荐使用接口{@link OH_AVScreenCapture_OnError}、{@link OH_AVScreenCapture_OnBufferAvailable}替代。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 * @since 10
 * @version 1.0
 */
typedef struct OH_AVScreenCaptureCallback {
    /**
     * @brief 监控录屏调用操作错误。\n
     * 从API 12开始，推荐使用接口{@link OH_AVScreenCapture_OnError}替代。
     */
    OH_AVScreenCaptureOnError onError;
    /**
     * @brief 监控音频码流是否有数据产生。\n
     * 从API 12开始，推荐使用接口{@link OH_AVScreenCapture_OnBufferAvailable}替代。
     */
    OH_AVScreenCaptureOnAudioBufferAvailable onAudioBufferAvailable;
    /**
     * @brief 监控视频码流是否有数据产生。\n
     * 从API 12开始，推荐使用接口{@link OH_AVScreenCapture_OnBufferAvailable}替代。
     */
    OH_AVScreenCaptureOnVideoBufferAvailable onVideoBufferAvailable;
} OH_AVScreenCaptureCallback;

/**
 * @brief 定义录屏界面的宽高以及画面信息。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 *
 * @since 10
 * @version 1.0
 */
typedef struct OH_Rect {
    /** 录屏界面的X坐标。 **/
    int32_t x;
    /** 录屏界面的Y坐标。 **/
    int32_t y;
    /** 录屏界面的宽度，单位px。 **/
    int32_t width;
    /** 录屏界面的高度，单位px。 **/
    int32_t height;
} OH_Rect;


/**
 * @brief 定义了音频数据的大小、类型、时间戳等配置信息。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 *
 * @since 10
 * @version 1.0
 */
typedef struct OH_AudioBuffer {
    /** 音频buffer内存。  **/
    uint8_t *buf;
    /** 音频buffer内存大小。 **/
    int32_t size;
    /** 音频buffer时间戳。 **/
    int64_t timestamp;
    /** 音频录制源类型。 **/
    OH_AudioCaptureSourceType type;
} OH_AudioBuffer;

/**
 * @brief 枚举，表示状态码。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 *
 * @since 12
 * @version 1.0
 */
typedef enum OH_AVScreenCaptureStateCode {
    /** 已开始录屏。 **/
    OH_SCREEN_CAPTURE_STATE_STARTED = 0,
    /** 已取消录屏。 **/
    OH_SCREEN_CAPTURE_STATE_CANCELED = 1,
    /** 已停止录屏。 **/
    OH_SCREEN_CAPTURE_STATE_STOPPED_BY_USER = 2,
    /** 录屏被其他录屏中断。 **/
    OH_SCREEN_CAPTURE_STATE_INTERRUPTED_BY_OTHER = 3,
    /** 录屏被通话中断。 **/
    OH_SCREEN_CAPTURE_STATE_STOPPED_BY_CALL = 4,
    /** 麦克风不可用。 **/
    OH_SCREEN_CAPTURE_STATE_MIC_UNAVAILABLE = 5,
    /** 麦克风被静音。 **/
    OH_SCREEN_CAPTURE_STATE_MIC_MUTED_BY_USER = 6,
    /** 麦克风被取消静音。 **/
    OH_SCREEN_CAPTURE_STATE_MIC_UNMUTED_BY_USER = 7,
    /** 进入隐私界面。 **/
    OH_SCREEN_CAPTURE_STATE_ENTER_PRIVATE_SCENE = 8,
    /** 隐私界面退出。 **/
    OH_SCREEN_CAPTURE_STATE_EXIT_PRIVATE_SCENE = 9,
    /** 系统用户切换，录屏中断。 **/
    OH_SCREEN_CAPTURE_STATE_STOPPED_BY_USER_SWITCHES = 10,
} OH_AVScreenCaptureStateCode;

/**
 * @brief 枚举，表示buffer类型。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 *
 * @since 12
 * @version 1.0
 */
typedef enum OH_AVScreenCaptureBufferType {
    /** 视频数据。 **/
    OH_SCREEN_CAPTURE_BUFFERTYPE_VIDEO = 0,
    /** 内录音频数据。 **/
    OH_SCREEN_CAPTURE_BUFFERTYPE_AUDIO_INNER = 1,
    /** 麦克风音频数据。 **/
    OH_SCREEN_CAPTURE_BUFFERTYPE_AUDIO_MIC = 2,
} OH_AVScreenCaptureBufferType;

/**
 * @brief 枚举，表示可过滤的音频类型。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 *
 * @since 12
 * @version 1.0
 */
typedef enum OH_AVScreenCaptureFilterableAudioContent {
    /** 通知音。 **/
    OH_SCREEN_CAPTURE_NOTIFICATION_AUDIO = 0,
    /** 应用自身声音。 **/
    OH_SCREEN_CAPTURE_CURRENT_APP_AUDIO = 1,
} OH_AVScreenCaptureFilterableAudioContent;

/**
 * @brief 枚举，表示录屏内容变更事件。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 *
 * @since 20
 */
typedef enum OH_AVScreenCaptureContentChangedEvent_Enum {
    /* 录屏内容变为隐藏。 */
    OH_SCREEN_CAPTURE_CONTENT_HIDE = 0,
    /* 录屏内容变为可见。 */
    OH_SCREEN_CAPTURE_CONTENT_VISIBLE = 1,
    /* 录屏内容状态变化为不可用，如录屏窗口关闭。 */
    OH_SCREEN_CAPTURE_CONTENT_UNAVAILABLE = 2,
} OH_AVScreenCaptureContentChangedEvent;

/**
 * @brief 图像填充模式。
 *
 * @since 20
 */
typedef enum OH_AVScreenCapture_FillMode {
    /** 
     * 保持图像原始宽高比匹配目标图像大小，若比例不一致可能存在黑边。 
     */
    OH_SCREENCAPTURE_FILLMODE_ASPECT_SCALE_FIT = 0,
    /** 
     * 图像拉伸匹配目标图像大小，若比例不一致图像变形。 
     */
    OH_SCREENCAPTURE_FILLMODE_SCALE_TO_FILL = 1,
} OH_AVScreenCapture_FillMode;

/**
 * @brief 当OH_AVScreenCapture实例操作期间发生状态变更时，将调用函数指针。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 * @param capture 指向OH_AVScreenCapture实例的指针。
 * @param stateCode 指定状态码。
 * @param userData 指向应用设置该回调处理方法时提供的自定义数据的指针。
 *
 * @since 12
 * @version 1.0
 */
typedef void (*OH_AVScreenCapture_OnStateChange)(struct OH_AVScreenCapture *capture,
    OH_AVScreenCaptureStateCode stateCode, void *userData);

/**
 * @brief 当OH_AVScreenCapture实例操作期间发生错误时，将调用函数指针。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 * @param capture 指向OH_AVScreenCapture实例的指针。
 * @param errorCode 指定错误码。
 * @param userData 指向应用设置该回调处理方法时提供的自定义数据的指针。
 *
 * @since 12
 * @version 1.0
 */
typedef void (*OH_AVScreenCapture_OnError)(OH_AVScreenCapture *capture, int32_t errorCode, void *userData);

/**
 * @brief 当OH_AVScreenCapture实例操作期间音频或视频缓存区可用时，将调用该函数指针。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 * @param capture 指向OH_AVScreenCapture实例的指针。
 * @param buffer 指向OH_AVBuffer缓存区实例的指针，该回调方法执行结束返回后，数据缓存区不再有效。
 * @param bufferType 可用缓存区的数据类型。
 * @param timestamp 时间戳，单位纳秒。
 * @param userData 指向应用设置该回调处理方法时提供的自定义数据的指针。
 *
 * @since 12
 * @version 1.0
 */
typedef void (*OH_AVScreenCapture_OnBufferAvailable)(OH_AVScreenCapture *capture, OH_AVBuffer *buffer,
    OH_AVScreenCaptureBufferType bufferType, int64_t timestamp, void *userData);

/**
 * @brief 当录屏事件开始时，将调用函数指针。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 * @param capture 指向OH_AVScreenCapture实例的指针。
 * @param displayId 录屏屏幕的Id。
 * @param userData 指向应用设置该回调处理方法时提供的自定义数据的指针。
 *
 * @since 15
 */
typedef void (*OH_AVScreenCapture_OnDisplaySelected)(OH_AVScreenCapture *capture, uint64_t displayId, void *userData);

/**
 * @brief 通过OH_AVScreenCapture_CaptureStrategy设置录屏策略。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 *
 * @since 20
 */
typedef struct OH_AVScreenCapture_CaptureStrategy OH_AVScreenCapture_CaptureStrategy;

/**
 * @brief 当OH_AVScreenCapture实例操作期间录屏内容变化时，将调用函数指针。
 * @syscap SystemCapability.Multimedia.Media.AVScreenCapture
 * @param capture 指向OH_AVScreenCapture实例的指针。
 * @param event 录屏内容变更事件。
 * @param area 录屏内容可见时，对应位置信息。
 * @param userData 指向应用设置该回调处理方法时提供的自定义数据的指针。
 *
 * @since 20
 * @version 1.0
 */
typedef void (*OH_AVScreenCapture_OnCaptureContentChanged)(OH_AVScreenCapture* capture,
    OH_AVScreenCaptureContentChangedEvent event, OH_Rect* area, void *userData);

/**
 * @brief 通过OH_AVScreenCapture_UserSelectionInfo获取用户在授权界面（选择界面）选择的参数。
 *
 * @since 20
 */
typedef struct OH_AVScreenCapture_UserSelectionInfo OH_AVScreenCapture_UserSelectionInfo;

/**
* @brief 当用户在授权界面（选择界面）选择参数时，功能接口将参数返回给应用程序。
* @param capture 指向OH_AVScreenCapture实例的指针。
* @param selections 用户在授权界面选择的录制参数信息。
* @param userData 指向用户数据的指针。
*
* @since 20
*/
typedef void (*OH_AVScreenCapture_OnUserSelected)(OH_AVScreenCapture* capture,
    OH_AVScreenCapture_UserSelectionInfo* selections, void *userData);
#ifdef __cplusplus
}
#endif

#endif // NATIVE_AVSCREEN_CAPTURE_BASE_H
/** @} */